package to.blacksheep.SpeedCourtManager;

import android.app.Activity;
import android.graphics.drawable.TransitionDrawable;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;

public class SpeedCourtManagerActivity extends Activity {
	
	private final int COURT_LEFT  = 0;
	private final int COURT_RIGHT = 1;
	private final int MAX_SERVES  = 3;
	private final int MAX_SETS	  = 3;	// TESTING: Konfigurierbar machen
	
	private Integer[] score    = new Integer[] {0, 0};
	private Integer[] wins	   = new Integer[] {0, 0};
	private Boolean[] serve    = new Boolean[] {false, false};
	private boolean   serveOne = false;
	private int		  serveCnt = 0;
	private int		  setCnt   = 0;
	private Integer	  lastMatchball = null;
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        initUI();
    }
    
    private void initUI() {
    	newGame();
    }
    
    private void newGame() {
    	resetServeCount(COURT_LEFT);
    	resetServeCount(COURT_RIGHT);
    	resetScores();
    	resetMatchball();
    	resetServeOne();
    	resetSetCount();
    	resetSetWins();    	
    }
    
    private void newSet(int court) {
    	resetServeCount(COURT_LEFT);
    	resetServeCount(COURT_RIGHT);
    	resetScores();
    	resetMatchball();
    	resetServeOne();
    	setServee(court);
    	incServeCount();
    	incSetCount();
    }
    
    public void buttonScoreUp(View v) {
    	int court = getCourtFromButtonId(v.getId());
    	switch (court) {
    	case COURT_LEFT:
    		scoreUp(COURT_LEFT);
    		break;
    	case COURT_RIGHT:
    		scoreUp(COURT_RIGHT);
    		break;
    	}
    }
    
    private void scoreUp(int court) {
    	Integer winner;
    	if (noServee()) {
			setServee(court);
			incSetCount();
		} else {
			incScore(court);
			winner = getSetWinner();
			if (winner != null) {
				announceSetWinner(winner);
				winner = getMatchWinner();
				if (winner != null) {
					announceMatchWinner(winner);
					newGame();
					return;
				}
				int oppositeCourt = (court == COURT_LEFT) ? COURT_RIGHT : COURT_LEFT;
				newSet(oppositeCourt);
				return;
			}
			if (checkMatchball() && (lastMatchball == null)) {
				announceMatchball();
			} else if (!checkMatchball() && (lastMatchball != null)){
				resetMatchball();
			}
		}
		incServeCount();
    }
    
    private void announceSetWinner(int court) {
    	
    }
    
    private void announceMatchWinner(int court) {
    	
    }
    
    private void announceMatchball() {
    	int court = COURT_RIGHT;
    	if (this.score[COURT_LEFT] > this.score[COURT_RIGHT]) {
    		court = COURT_LEFT;
    	}
    	transitionMatchball(court, true);
    	lastMatchball = court;
    }
    
    private void transitionMatchball(int court, boolean isMatchball) {
    	ImageButton button = new ImageButton(this);
    	switch (court) {
    	case COURT_LEFT:
    		button = (ImageButton) findViewById(R.id.leftCourt);
    		break;
    	case COURT_RIGHT:
    		button = (ImageButton) findViewById(R.id.rightCourt);
    		break;
    	}    	
    	TransitionDrawable drawable = (TransitionDrawable) button.getDrawable();
    	if (isMatchball) {
    		drawable.startTransition(500);
    	} else {
    		drawable.resetTransition();
    	}
    }
    
    private void resetMatchball() {
    	if (lastMatchball != null) {
    		transitionMatchball(lastMatchball, false);
    		lastMatchball = null;
    	}
    }
    
    private int getCourtFromButtonId(int id) {
    	return (id == R.id.buttonLeftScoreUp) ? COURT_LEFT : COURT_RIGHT;
    }
    
    private Integer getMatchWinner() {
    	Integer winner = null;
    	if ((this.wins[COURT_LEFT] + this.wins[COURT_RIGHT]) == MAX_SETS) {
    		if (this.wins[COURT_LEFT] > this.wins[COURT_RIGHT]) {
    			winner = COURT_LEFT;
    		} else {
    			winner = COURT_RIGHT;
    		}
    	}
    	return winner;
    }
    
    private Integer getSetWinner() {
    	Integer winner = null;
    	if ((this.score[COURT_LEFT] > 15) || (this.score[COURT_RIGHT] > 15)) {
    		if (Math.abs(this.score[COURT_LEFT] - this.score[COURT_RIGHT]) >= 2) {
    			if (this.score[COURT_LEFT] > this.score[COURT_RIGHT]) {
    				winner = COURT_LEFT;
    				this.wins[COURT_LEFT]++;
    			} else {
    				winner = COURT_RIGHT;
    				this.wins[COURT_RIGHT]++;
    			}
    		} 
    	}
    	return winner;
    }
    
    private void resetSetWins() {
    	this.wins = new Integer[] {0,0};
    }
    
    private boolean checkMatchball() {
    	boolean matchball = false;
    	if ((this.score[COURT_LEFT] >= 15) || (this.score[COURT_RIGHT] >= 15)) {
    		if (Math.abs(this.score[COURT_LEFT] - this.score[COURT_RIGHT]) >= 1) {
    			matchball = true;
    		}
    	}
    	return matchball;
    }
    
    private void setSetCount(int set) {
    	this.setCnt = set;
    	setSetCountVisible(set);
    }
    
    private int getSetCount() {
    	return this.setCnt;
    }
    
    private void incSetCount() {
    	int set = getSetCount()+1;
    	setSetCount(set);
    }
    
    private void setSetCountVisible(int set) {
    	TextView v = (TextView) findViewById(R.id.setNumber);
    	String txt = getString(R.string.set_number, set);
    	v.setText(txt);
    }
    
    private void resetSetCount() {
    	setSetCount(0);
    }
    
    private void setScore(int court, int score) {
    	this.score[court] = score;
    	setScoreVisible(court, score);
    }
    
    private int getScore(int court) {
    	return this.score[court];
    }
    
    private void incScore(int court) {
    	int score = getScore(court)+1;
    	setScore(court, score);
    }
    
    private void decScore(int court) {
    	int score = getScore(court)-1;
    	setScore(court, score);
    }
    
    private void resetScores() {
    	setScore(COURT_LEFT, 0);
    	setScore(COURT_RIGHT, 0);
    }
    
    private void setScoreVisible(int court, int score) {
    	TextView v = null;
    	switch (court) {
    	case COURT_LEFT:
    		v = (TextView) findViewById(R.id.leftScore);
    		v.setText(String.valueOf(score));
    		break;
    	case COURT_RIGHT:
    		v = (TextView) findViewById(R.id.rightScore);
    		v.setText(String.valueOf(score));
    		break;
    	}
    }
    
    private void setServee(int court) {
    	if (court == COURT_RIGHT) {
    		serve[COURT_LEFT]  = false;
    		serve[COURT_RIGHT] = true;
    	} else {
    		serve[COURT_RIGHT] = false;
    		serve[COURT_LEFT]  = true;
    	}
    }
    
    private int getServee() {
    	return (this.serve[COURT_LEFT]) ? COURT_LEFT : COURT_RIGHT;
    }
    
    private boolean noServee() {
    	return (!this.serve[COURT_LEFT] && !this.serve[COURT_RIGHT]);
    }
    
    private void interchangeServee() {
    	if (getServee() == COURT_LEFT) {
    		serve[COURT_LEFT]  = false;
    		serve[COURT_RIGHT] = true;
    	} else {
    		serve[COURT_RIGHT] = false;
    		serve[COURT_LEFT]  = true;
    	}
    }
    
    private void checkServeOne() {
    	if ((this.score[COURT_LEFT] >= 15) && (this.score[COURT_RIGHT] >= 15)) {
			this.serveOne = true;
		}
    }
    
    private boolean isServeOne() {
    	return this.serveOne;
    }
    
    private void resetServeOne() {
    	this.serveOne = false;
    }
    
    private void setServeCount(int serve) {
    	setServeCount(getServee(), serve);
    }
    
    private void setServeCount(int court, int serve) {
    	serveCnt = serve;
    	if (serve == 0) {
    		for (int i=1;i<=MAX_SERVES;i++) {
    			setServeVisible(court, i, View.INVISIBLE);
    		}
    	} else {
    		for (int i=1;(i<=serve)&&(i<=MAX_SERVES);i++) {
    			setServeVisible(court, i, View.VISIBLE);
    		}
    	}
    }
    
    private int getServeCount() {
    	return this.serveCnt;
    }
    
    private void incServeCount() {
    	checkServeOne();
    	if (!isServeOne()) {
	    	if (getServeCount() < MAX_SERVES) {
	    		setServeCount(getServeCount()+1);
	    	} else {
	    		resetServeCount(getServee());
	    		interchangeServee();
	    		setServeCount(getServeCount()+1);
	    	}
    	} else {
    		resetServeCount(getServee());
    		interchangeServee();
    		setServeCount(getServeCount()+1);
    	}
    }
    
    private void resetServeCount(int court) {
    	setServeCount(court, 0);
    }
    
    private void setServeVisible(int court, int serve, int visible) {
    	ImageView v = null;
    	switch (court) {
    	case COURT_LEFT:
    		switch (serve) {
    		case 1:
    			v = (ImageView) findViewById(R.id.leftFirstServe);
    			v.setVisibility(visible);
    			break;
    		case 2:
    			v = (ImageView) findViewById(R.id.leftSecondServe);
    			v.setVisibility(visible);
    			break;
    		case 3:
    			v = (ImageView) findViewById(R.id.leftThirdServe);
    			v.setVisibility(visible);
    			break;
    		}
    		break;
    	case COURT_RIGHT:
    		switch (serve) {
    		case 1:
    			v = (ImageView) findViewById(R.id.rightFirstServe);
    			v.setVisibility(visible);
    			break;
    		case 2:
    			v = (ImageView) findViewById(R.id.rightSecondServe);
    			v.setVisibility(visible);
    			break;
    		case 3:
    			v = (ImageView) findViewById(R.id.rightThirdServe);
    			v.setVisibility(visible);
    			break;
    		}
    		break;
    	}
    }
}